/**
 * 阡陌时空内部使用JS， 配合后台框架使用。 jinglupeng@hotmail.com 2014-03-04
 * 文档地址：https://github.com/jinglupeng/qmsk/blob/master/release/qmsk-1.1.md
 * last modify: 201404021109
 * 优化 Response.getValue 方法
 * 添加Response.addColsValue 方法
 * 扩展qmsk.initSelect 方法
 *
 * last modify: 201404111554
 * 添加调试模式
 * 添加 qmsk.debug 属性 true:调试模式，false:正常模式
 * 添加 对 简单对象的处理方法
 * dataTable 可以不清空本来的数据
 * 修复同步Get 和同步Post bug
 */
(function(window, $) {

	if (!$) {
		alert("jQuery is needed!");
		return;
	}

	function Qmsk() {
		this.debug = false;
	}

	var qm = Qmsk.prototype;
	function Response(rst) {
		this.rst = rst;
		if ( typeof rst.msg !== "undefined")
			this.msg = rst.msg;
		if ( typeof rst.state !== "undefined")
			this.state = rst.state;
		if ( typeof rst.result !== "undefined") {
			if ( typeof rst.result.len !== "undefined")
				this.length = rst.result.len;
			if (rst.result.head instanceof Array) {
				this.heads = rst.result.head;
				this.col = rst.result.head.length;
			}
			if (rst.result.data instanceof Array) {
				this.data = rst.result.data;
				this.row = rst.result.data.length;
			}
		}
	}


	Response.prototype.getValue = function(key, r) {
		r = (arguments.length === 1 ? 0 : r);
		var i = 0;
		for (; i < this.col; i++)
			if (key.toLocaleLowerCase() === this.heads[i].toLocaleLowerCase())
				break;
		if (i < this.col) {
			var value = this.data[r][i];
			value = (value === null ? '' : value);
			var emptyDataPattren = /\d\d-\d\d-\d\d 00:00:00/;
			if (emptyDataPattren.test(value)) {
				return value.substring(0, 10);
			}
			return value;
		} else {
			return '';
		}
	};

	Response.prototype.getObject = function(heads, row) {
		if (arguments.length == 0) {
			row = 0;
			heads = this.heads;
		} else if (arguments.length == 1) {
			row = 0;
		}
		var data = {};
		for (var i = 0; i < heads.length; i++) {
			var tempValue = this.getValue(heads[i], row);
			if (isEmpty(tempValue)) {
				tempValue = '';
			}
			debug("Turn Row To Object :" + heads[i] + ' : ' + tempValue);
			data[heads[i]] = tempValue;
		}

		return data;
	};

	/**
	 * 打印调试信息，每次只打印一行
	 */
	function debug() {
		if (!qmsk.debug)
			return;
		var debug = 'DEBUG ';
		for (var i = 0; i < arguments.length; i++) {
			debug = debug + arguments[i] + ' ';
		}
		console.debug(debug);
	}


	Response.prototype.addColsValue = function(keys, values) {

		if (!( keys instanceof Array)) {
			var temp = [];
			temp.push(keys);
			keys = temp;
		}

		if (!( values instanceof Array)) {
			console.log('1');
			var temp = [];
			temp.push(values);
			values = temp;
		}

		var temp = values[0];
		if (!( temp instanceof Array)) {
			var temp1 = [];
			temp1.push(values);
			values = temp1;
		}

		for (var i = 0; i < keys.length; i++) {
			this.heads.push(keys[i]);
		}

		for (var i = 0; i < this.row; i++) {
			for (var j = 0; j < keys.length; j++) {
				this.data[i][this.col + j] = values[i][j];
			}
		}

		this.col = this.heads.length;

	};
	function get(url, data, success) {
		debug('----------GET Start----------');
		if (arguments.length == 3) {
			ajax('GET', arguments[0], arguments[1], arguments[2]);
		} else {
			ajax('GET', arguments[0], {}, arguments[1]);
		}
		debug('----------GET End----------');
	}

	function post(url, data, success) {
		debug('----------POST Start----------');
		if (arguments.length == 3) {
			ajax('POST', arguments[0], arguments[1], arguments[2]);
		} else {
			ajax('POST', arguments[0], {}, arguments[1]);
		}
		debug('----------POST End----------');
	}

	/**
	 * 同步的 GET方法
	 * @param {Object} url
	 * @param {Object} data
	 * @sinece 1.2
	 */
	function asynGet(url, data) {
		if (arguments.length == 2) {
			return asynAjax('GET', arguments[0], arguments[1]);
		} else {
			return asynAjax('GET', arguments[0], {});
		}

	}

	/**
	 * 同步的 POST 方法
	 * @param {Object} url
	 * @param {Object} data
	 * @sinece 1.2
	 */
	function asynPost(url, data) {
		if (arguments.length == 2) {
			return asynAjax('POST', arguments[0], arguments[1]);
		} else {
			return asynAjax('POST', arguments[0], {});
		}
	}

	function asynAjax(methodType, url, data) {

		var _response = null;

		data = cleanObject(data);
		$.ajax({
			type : methodType,
			async : false,
			data : data,
			datatype : "json",
			url : url,
			success : function(rst) {
				if ( typeof rst === "string") {
					rst = JSON.parse(rst);
				}
				if (isEmpty(rst)) {
					if ( typeof artError == "function")
						artError('服务器忙，请联系系统管理员！');
					else {
						alert('服务器忙，请联系系统管理员！');
					}
					return;
				}
				var response = new Response(rst);
				if (response.state == 0) {
					_response = response;
				} else if (response.state == 1) {
					if ( typeof artError == "function")
						artError(response.msg);
					else {
						alert(response.msg);
					}
				} else {
					if ( typeof checkStateShowErrorMsgAndDealResult == "function")
						checkStateShowErrorMsgAndDealResult(JSON.stringify(rst));
				}
			}
		});
		return _response;
	}

	function ajax(methodType, url, data, success) {

		data = cleanObject(data);
		debug("URL:" + url);
		if (qmsk.debug) {
			for (var key in data) {
				console.log(key + " : " + data[key]);
			}
		}

		var method = $.get;
		if (methodType === "POST") {
			method = $.post;
		}

		method(url, data, function(rst) {
			if (isEmpty(rst)) {
				if ( typeof artError == "function")
					artError('服务器忙，请联系系统管理员！');
				else {
					alert('服务器忙，请联系系统管理员！');
				}
				return;
			}
			var response = new Response(rst);
			if (response.state == 0) {
				success(response);
			} else if (response.state == 1) {
				if ( typeof artError == "function")
					artError(response.msg);
				else {
					alert(response.msg);
				}
			} else {
				if ( typeof checkStateShowErrorMsgAndDealResult == "function")
					checkStateShowErrorMsgAndDealResult(JSON.stringify(rst));
			}
		}, "json");
	}

	function isEmpty(value, isNotTrim) {
		if ( typeof value === "undefined") {
			return true;
		}
		if ( typeof value === "object") {
			return value === null;
		}
		var str = value.toString();
		if (!isNotTrim) {
			str = str.replace(/\s/igm, '');
		}
		return str.length === 0;
	}

	function isNotEmpty(value, isNotTrim) {
		if (!isNotTrim) {
			return !isEmpty(value, false);
		}
		return isEmpty(value);
	}

	function getQueryValue(key) {
		var qs = (location.search.length > 0 ? location.search.substring(1) : '');
		var items = qs.length ? qs.split("&") : [];
		var item = null;
		var name = null;
		var value = null;
		for (var i = 0; i < items.length; i++) {
			item = items[i].split("=");
			name = decodeURIComponent(item[0]);
			value = decodeURIComponent(item[1]);
			if (name.length && name == key) {
				return value;
			}
		}
		return '';
	}

	function cleanObject(data) {
		for (key in data) {
			var value = data[key];
			if (value === '' || value === null || value === undefined)
				delete data[key];
			if ( typeof value == "number" && isNaN(value))
				delete data[key];
		}
		return data;
	}

	function redirectUrl(url, data) {
		window.location.href = generateUrl(url, data);
	}

	function generateUrl(url, data) {
		if ( typeof data === "undefined") {
			data = {};
		}
		data = cleanObject(data);
		var params = '';
		for (key in data) {
			params += ('&' + key + '=' + encodeURIComponent(data[key]));
		}
		return url + '?' + params.substring(1);
	}

	function initSelect(options) {

		if ( typeof options.datas != "undefined") {
			var datas = options.datas;
			var $select = $("#" + options.id);
			$select.empty();
			if (options.defaults) {
				var key = options.defaults.key;
				var value = options.defaults.value;
				var $option = $("<option>" + key + "</option>");
				if (value) {
					$option.val(value);
				}
				$select.append($option);
			}
			var row = datas.length;
			for (var i = 0; i < row; i++) {
				var value = datas[i][0];
				var key = datas[i][1];
				var $option = $("<option value='" + value + "'>" + key + "</option>");
				$select.append($option);
			}
			return;
		}

		if ( typeof options.response != "undefined") {
			handler(options.response);
			return;
		}

		ajax(options.method, options.url, options.data, handler);
		function handler(response) {
			var $select = $("#" + options.id);
			$select.empty();
			if (options.defaults) {
				var key = options.defaults.key;
				var value = options.defaults.value;
				var $option = $("<option>" + key + "</option>");
				if (value) {
					$option.val(value);
				}
				$select.append($option);
			}
			var row = response.row;
			for (var i = 0; i < row; i++) {
				var value = response.getValue(options.heads[0], i);
				var key = response.getValue(options.heads[1], i);
				var $option = $("<option value='" + value + "'>" + key + "</option>");
				$select.append($option);
			}
		}

	}

	function ansyInitSelect(options) {

		var response = asynAjax(options.method, options.url, options.data);
		var $select = $("#" + options.id);
		$select.empty();
		if (options.defaults) {
			var key = options.defaults.key;
			var value = options.defaults.value;
			var $option = $("<option>" + key + "</option>");
			if (value) {
				$option.val(value);
			}
			$select.append($option);
		}
		var row = response.row;
		for (var i = 0; i < row; i++) {
			var value = response.getValue(options.heads[0], i);
			var key = response.getValue(options.heads[1], i);
			var $option = $("<option value='" + value + "'>" + key + "</option>");
			$select.append($option);
		}
	}

	function dataTable(customerOptions) {

		var defaultHandler = function(args, row) {
			if ( args instanceof Array) {
				return args[0];
			}
			return args;
		};

		var defaultTrGender = function(row) {
			return "<tr></tr>";
		};

		var defaultDataTableOptions = {
			tableId : '',
			tbodyId : 'tbodyId',
			theads : [],
			heads : [],
			response : {},
			sup : ['sup', '共 [index] 条'],
			handler : [],
			empty : true,
			trGender : defaultTrGender
		};

		var options = $.extend(true, {}, defaultDataTableOptions, customerOptions);

		var response = options.response;
		var $tbody = null;
		if (isNotEmpty(options.tableId)) {
			var $table = $("#" + options.tableId);
			$("#" + options.tableId + "> tbody").remove();
			$("#" + options.tableId + "> thead").remove();
			$thead = $("<thead></thead>");
			$tbody = $("<tbody></tbody>");
			$tr = $("<tr></tr>");
			$tr.appendTo($thead);

			for (var i = 0; i < options.theads.length; i++) {
				var thead = options.theads[i];
				var $th = $("<th>" + thead + "</th>");
				$tr.append($th);
			}

			$table.append($thead);
			$table.append($tbody);

		} else {
			var $tbody = $("#" + options.tbodyId);
		}

		if (options.empty) {
			$tbody.empty();
		}
		var cols = options.heads.length;
		var rows = response.row;

		var handlers = [];
		for (var k = 0; k < cols; k++) {
			handlers[k] = defaultHandler;
		}
		for (var k = 0; k < options.handler.length; k++) {
			var col = options.handler[k][0];
			var handler = options.handler[k][1];
			handlers[Number(col)] = handler;
		}

		for (var i = 0; i < rows; i++) {
			var tr = options.trGender(i);
			var $tr = $(tr);
			for (var j = 0; j < cols; j++) {

				var heads = [];
				if (options.heads[j] instanceof Array) {
					heads = options.heads[j];
				} else {
					heads.push(options.heads[j]);
				}

				var args = [];
				for (var k = 0; k < heads.length; k++) {
					var value = response.getValue(heads[k], i);
					args.push(value);
				}
				args.push(i);
				var td = handlers[j].apply(this, args);
				var $td = $("<td>" + td + "</td>");
				$tr.append($td);
			}
			$tbody.append($tr);
		}

		if (customerOptions.sup) {
			var supId = options.sup[0];
			var template = options.sup[1].replace("[index]", response.length);
			$("#" + supId).text(template);
		}
	}

	function siglePinterest(options) {

		var current = 0;

		var lock = 0;

		var defaults = {
			method : 'get', // post|get
			url : '', // 请求地址，插件会自动在 url 后追加 /n/n
			data : {}, // 使用post 方法是的请求参数
			initPage : 5, // 首次加载数量
			size : 0, // 每次加载数量
			success : success, // state 为 0 回调
			valves : 100, //阀值
			emptyHandler : emptyHandler, //空数据回调
			loading : loading, //开始加载
			loaded : loaded	//加载完毕		};

		function loading() {
		}

		function loaded() {
		}

		function success() {
		}

		function emptyHandler() {
		}

		options = $.extend(true, {}, defaults, options);
		var method = (options.method).toUpperCase();

		function loadData(start, size) {

			var argsLength = arguments.length;
			if (lock !== 0) {
				return;
			}
			lock = 1;
			options.loading();
			var url = options.url + '/' + start + '/' + size;
			ajax(method, url, options.data, function(response) {
				current += size / options.size;
				var row = response.row;
				if (argsLength == 3 && row === 0) {
					options.emptyHandler.call(this);
				}
				if (row < options.size) {
					$(window).unbind("scroll");
				}
				options.success.call(this, response);
				lock = 0;
				options.loaded();
			});
		}

		function bindEvent(valves) {
			$(window).bind("scroll", function() {
				var documentHeight = $(document).height();
				var windowHeight = $(window).height();
				var scrollHeight = documentHeight - windowHeight;
				var scrollTop = $(window).scrollTop();
				var scrollDowm = documentHeight - windowHeight - scrollTop;
				if (scrollDowm <= valves && scrollDowm % (valves / 10) === 0) {
					var oldScrollTop = scrollTop;
					loadData(current, options.size);
					$(window).scrollTop(oldScrollTop);
					if ($(document).height() - $(window).height() - $(window).scrollTop() === 0) {
					}
				}
			});
		}

		var size = Number(options.initPage) * Number(options.size);
		loadData(0, size, 1);
		//首次加载
		//loadData(options.initSize);
		//注册事件
		bindEvent(options.valves);
	}

	/**
	 * 将一个简单Bean 打印到页面上，是下一个版本的开端
	 * @param {Object} bean
	 */
	function bindBean(bean) {
		debug('----------Bind Bean Start----------');
		for (var key in bean) {
			var value = bean[key];
			$("#" + key).val(value);
			debug('Bind ' + key + ' : ' + value);
		}
		debug('----------Bind Bean End----------');
	}

	function bindData(response, row, heads, ids) {
		debug('----------Bind Date Start----------');
		if (arguments.length == 1) {
			row = 0;
			ids = heads = response.heads;
		} else if (arguments.length == 2) {
			ids = heads = response.heads;
		} else if (arguments.length == 3) {
			ids = heads;
		}
		for (var i = 0; i < heads.length; i++) {
			var head = heads[i];
			var value = response.getValue(head, row);
			debug('Bind ' + ids[i] + ' : ' + value);
			$("#" + ids[i]).val(value);
		}
		debug('----------Bind Date End----------');
	}

	function collectionData(heads, ids) {
		debug('----------Collection Data End----------');
		if (arguments.length === 1) {
			ids = heads;
		}

		var len = ids.length;
		//容错
		len = heads.length >= len ? len : heads.length;

		var data = {};
		for (var i = 0; i < len; i++) {
			var value = $("#" + ids[i]).val();
			debug('Collection ' + ids[i] + ' : ' + value);
			data[heads[i]] = value;
		}
		debug('----------Collection Data End----------');
		return data;
	}


	qm.get = get;
	qm.post = post;
	qm.asynGet = asynGet;
	qm.asynPost = asynPost;
	qm.isEmpty = isEmpty;
	qm.isNotEmpty = isNotEmpty;
	qm.getQueryValue = getQueryValue;
	qm.cleanObject = cleanObject;
	qm.generateUrl = generateUrl;
	qm.initSelect = initSelect;
	qm.ansyInitSelect = ansyInitSelect;
	qm.dataTable = dataTable;
	qm.redirectUrl = redirectUrl;
	qm.Response = Response;
	qm.SiglePinterest = siglePinterest;
	qm.bindBean = bindBean;
	qm.bindData = bindData;
	qm.collectionData = collectionData;
	var qmsk = new Qmsk();
	window.qmsk = qmsk;
})(window, typeof jQuery !== 'undefined' ? jQuery : null);
